package com.caltco.cargo.ops.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caltco.cargo.ops.auth.bo.AdminUserDetails;
import com.caltco.cargo.ops.common.base.gen.BaseServiceImpl;
import com.caltco.cargo.ops.common.exception.RRException;
import com.caltco.cargo.ops.common.utils.StringUtils;
import com.caltco.cargo.ops.modules.sys.dao.ProjectDao;
import com.caltco.cargo.ops.modules.sys.dao.ProjectUserDao;
import com.caltco.cargo.ops.modules.sys.dao.SysUserDao;
import com.caltco.cargo.ops.modules.sys.entity.Project;
import com.caltco.cargo.ops.modules.sys.entity.ProjectUser;
import com.caltco.cargo.ops.modules.sys.entity.SysUserEntity;
import com.caltco.cargo.ops.modules.sys.request.ProjectRequest;
import com.caltco.cargo.ops.modules.sys.service.ProjectService;
import com.caltco.cargo.ops.modules.sys.vo.ProjectVO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

@Service
public class ProjectServiceImp extends BaseServiceImpl<ProjectDao, Project> implements ProjectService {

    public final ProjectDao projectDao;
    private final ProjectUserDao projectUserDao;
    private final SysUserDao sysUserDao;

    public ProjectServiceImp(ProjectDao projectDao, ProjectUserDao projectUserDao, SysUserDao sysUserDao) {
        this.projectDao = projectDao;
        this.projectUserDao = projectUserDao;
        this.sysUserDao = sysUserDao;
    }

    public Long getUserIdByToken() {
        return ((AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserEntity().getUserId();
    }

    @Override
    public Boolean top(Long id, Integer isTop) {
        ProjectUser projectUser = projectUserDao.selectOne(new LambdaQueryWrapper<ProjectUser>()
                .eq(ProjectUser::getProjectId, id)
                .eq(ProjectUser::getUserId, getUserIdByToken()));
        projectUser.setIsTop(isTop);
        projectUserDao.updateById(projectUser);
        return true;
    }

    @Override
    public Boolean collection(Long id, Integer isCollection) {
        ProjectUser projectUser = projectUserDao.selectOne(new LambdaQueryWrapper<ProjectUser>()
                .eq(ProjectUser::getProjectId, id)
                .eq(ProjectUser::getUserId, getUserIdByToken()));
        projectUser.setIsCollection(isCollection);
        projectUserDao.updateById(projectUser);
        return true;
    }

    @Override
    public List<ProjectVO> get(ProjectRequest projectRequest) {
        Long userId = getUserIdByToken();
        List<ProjectVO> projectVOS = projectDao.selectJoinList(ProjectVO.class,
        new MPJLambdaWrapper<Project>()
                .selectAll(Project.class)
                .select(ProjectUser::getIsCreate)
                .select(ProjectUser::getIsCollection)
                .select(ProjectUser::getIsTop)
                .selectAs(Project::getCreateName, ProjectVO::getCreatePerson)
                .leftJoin(ProjectUser.class, ProjectUser::getProjectId, Project::getId)
                .leftJoin(SysUserEntity.class, SysUserEntity::getId, ProjectUser::getUserId)
                .eq(projectRequest.getId() != null, Project::getId, projectRequest.getId())
                .eq(projectRequest.getIsTop() != null, ProjectUser::getIsTop, projectRequest.getIsTop())
                .eq(projectRequest.getIsCollection() != null, ProjectUser::getIsCollection, projectRequest.getIsCollection())
                .like(StringUtils.isNotBlank(projectRequest.getProjectCode()), Project::getProjectCode, projectRequest.getProjectCode())
                .like(StringUtils.isNotBlank(projectRequest.getProjectName()), Project::getProjectName, projectRequest.getProjectName())
                .eq(SysUserEntity::getId, userId));
        return projectVOS;

    }

    @Override
    public List<ProjectVO> getCreate(ProjectRequest projectRequest) {
        Long userId = getUserIdByToken();

        List<ProjectVO> projectVOS = projectDao.selectJoinList(ProjectVO.class,
                new MPJLambdaWrapper<Project>()
                        .selectAll(Project.class)
                        .selectAs(Project::getCreateName, ProjectVO::getCreatePerson)
                        .leftJoin(ProjectUser.class, ProjectUser::getProjectId, Project::getId)
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, ProjectUser::getUserId)
                        .eq(projectRequest.getId() != null, Project::getId, projectRequest.getId())
                        .like(StringUtils.isNotBlank(projectRequest.getProjectCode()), Project::getProjectCode, projectRequest.getProjectCode())
                        .like(StringUtils.isNotBlank(projectRequest.getProjectName()), Project::getProjectName, projectRequest.getProjectName())
                        .eq(SysUserEntity::getId, userId)
                        .eq(ProjectUser::getIsCreate, 1));

        return projectVOS;
    }

    @Override
    public List<ProjectVO> getJoin(ProjectRequest projectRequest) {
        Long userId = getUserIdByToken();
        List<ProjectVO> projectVOS = projectDao.selectJoinList(ProjectVO.class,
                new MPJLambdaWrapper<Project>()
                        .selectAll(Project.class)
                        .selectAs(Project::getCreateName, ProjectVO::getCreatePerson)
                        .leftJoin(ProjectUser.class, ProjectUser::getProjectId, Project::getId)
                        .leftJoin(SysUserEntity.class, SysUserEntity::getId, ProjectUser::getUserId)
                        .eq(projectRequest.getId() != null, Project::getId, projectRequest.getId())
                        .like(StringUtils.isNotBlank(projectRequest.getProjectCode()), Project::getProjectCode, projectRequest.getProjectCode())
                        .like(StringUtils.isNotBlank(projectRequest.getProjectName()), Project::getProjectName, projectRequest.getProjectName())
                        .eq(SysUserEntity::getId, userId)
                        .eq(ProjectUser::getIsCreate, 0)
        );

        return projectVOS;
    }

    @Override
    public Boolean remove(Long id) {
        return this.removeById(id);
    }

    @Override
    public List<SysUserEntity> getPersonList(Long id) {
        MPJLambdaWrapper<SysUserEntity> mpjLambdaWrapper = new MPJLambdaWrapper<SysUserEntity>()
                .leftJoin(ProjectUser.class, ProjectUser::getUserId, SysUserEntity::getId)
                .leftJoin(Project.class, Project::getId, ProjectUser::getProjectId)
                .eq(Project::getId, id);
        return sysUserDao.selectList(mpjLambdaWrapper);
    }

    @Override
    public Boolean save(ProjectRequest projectRequest) {
        projectRequest.setId(null);
        Project project = new Project();
        BeanUtil.copyProperties(projectRequest, project);
        project.setProjectCode(String.valueOf(UUID.randomUUID()));
        this.save(project);

        ProjectUser projectUser = new ProjectUser();
        projectUser.setProjectId(project.getId());
        projectUser.setUserId(getUserIdByToken());
        projectUser.setIsCreate(1);
        projectUserDao.insert(projectUser);
        return true;
    }

    @Override
    public Boolean update(ProjectRequest projectRequest) {
        if (projectRequest.getId() == null) {
            throw new RRException("id为空");
        }
        Project project = new Project();
        BeanUtil.copyProperties(projectRequest, project);
        return this.saveOrUpdate(project);
    }

    @Override
    public Boolean join(ProjectRequest projectRequest) {
        Long userId = getUserIdByToken();
        Project project = this.getOne(new QueryWrapper<Project>()
                .eq("project_code", projectRequest.getProjectCode()));
        if (project == null) {
            throw new RRException("项目编码输入错误");
        }
        Long projectId = project.getId();

        Boolean isExist = projectUserDao.exists(new QueryWrapper<ProjectUser>()
                .eq("user_id", userId)
                .eq("project_id", projectId));
        if (isExist) {
            throw new RRException("您已在该项目中，无需在加入");
        } else {
            ProjectUser projectUser = new ProjectUser();
            projectUser.setIsCreate(0);
            projectUser.setUserId(userId);
            projectUser.setProjectId(projectId);
            projectUserDao.insert(projectUser);
        }
        return true;
    }
}
